package com.tinusgraglin.enclusiv.datalayer.datasources

import android.util.Log
import com.squareup.moshi.JsonDataException
import com.tinusgraglin.enclusiv.datalayer.BasicArticleProfile
import com.tinusgraglin.enclusiv.datalayer.Exceptions
import com.tinusgraglin.enclusiv.datalayer.RemoteSourceCommunication
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import okio.IOException
import org.json.JSONArray
import org.json.JSONObject

class ArticleRemoteSource(private val communication: RemoteSourceCommunication) {
    private val serverUrl = communication.serverUrl
    private val client = communication.client

    private val resultStrArticleProfileAdaptor =
        communication.newResultStrDataPairAdaptor<BasicArticleProfile>(BasicArticleProfile::class.java)

    fun upload(uid: Long, title: String, content: String, images: List<Long>): Long {
        val requestUrl = serverUrl.newBuilder()
            .addPathSegments("article/upload")
            .build()

        val requestBody = JSONObject().apply {
            put("title", title)
            put("authorId", uid.toString())
            put("article", content)
            put("imageIds", JSONArray())
        }.toString()

        Log.d("##DBG 8989", requestBody)

        val request = Request.Builder()
            .url(requestUrl)
            .post(requestBody.toRequestBody(communication.jsonMediaType))
            .build()

        val resp = client.newCall(request).execute()

        if (!resp.isSuccessful) {
            throw IOException("Request Error: ${resp.code}")
        } else {
            val responseStr = resp.body.string()

            val pairResponse = communication.resultStrLongDataResponseAdapter.fromJson(responseStr)
                ?: throw JsonDataException("Data conversion failed.")

            when (pairResponse.result) {
                "failed" -> throw Exceptions.UploadFailure()
                "success" -> return pairResponse.data!!
                else -> throw IllegalStateException("Unexpected Result String")
            }
        }
    }

    fun getArticle(aid: Long) : BasicArticleProfile {
        val requestUrl = serverUrl.newBuilder()
            .addPathSegments("article/article_info")
            .addQueryParameter("id", aid.toString())
            .build()

        val responseBody = communication.templateGet(requestUrl)

        val pairResponse = resultStrArticleProfileAdaptor.fromJson(responseBody.string())
            ?: throw JsonDataException("Data conversion failed.")

        when (pairResponse.result) {
            "article not found" -> throw Exceptions.ArticleNotFound()
            "success" -> return pairResponse.data!!
            else -> throw IllegalStateException("Unexpected Result String")
        }
    }
}